import asyncio

from uvicorn import Config, Server
from fastapi import FastAPI, Request
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import HTTPException
from fastapi.middleware.cors import CORSMiddleware
from starlette.responses import JSONResponse

from apis_module.api.group_api import groupMapping
from apis_module.api.login_api import loginMapping
from apis_module.api.reviews_api import reviewMapping
from apis_module.api.user_api import userMapping
from backend_module.api.login_api import backendLoginMapper
from backend_module.api.reviews_manage_api import reviewsManageMapper
from config.get_db import init_create_table, close_db_connection
from config.get_redis import RedisUtil
from utils.common_util import worship
from utils.log_util import logger
from utils.response_util import AuthException, response_401

app = FastAPI(title='Fei-Campus-Review-Apis'
              , description='Fei-Campus-Review-Apis 接口文档'
              , version='0.1')

origins = [
    "http://localhost:3000",
    "http://localhost:5173",
    "https://localhost:9500"
]

config = Config(app="app:app", host="0.0.0.0", port=9500, reload=True)
server = Server(config)

# 后台api允许跨域
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.on_event('startup')
async def startup_event():
    logger.info("Fei-Campus-Review-Apis开始启动")
    worship()
    await init_create_table()
    app.state.redis = await RedisUtil.create_redis_pool()
    # await RedisUtil.init_sys_dict(app.state.redis)
    # await RedisUtil.init_sys_config(app.state.redis)
    # await SchedulerUtil.init_system_scheduler()
    logger.info("Fei-Campus-Review-Apis启动成功")


@app.on_event("shutdown")
async def shutdown_event():
    await close_db_connection()
    await RedisUtil.close_redis_pool(app)
    # await SchedulerUtil.close_system_scheduler()
    server.should_exit = True
    await asyncio.sleep(3)
    logger.info("Fei-Campus-Review-Apis已停止运行")


# 自定义token检验异常
@app.exception_handler(AuthException)
async def auth_exception_handler(request: Request, exc: AuthException):
    return response_401(data=exc.data, message=exc.message)


@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    return JSONResponse(
        content=jsonable_encoder({"message": exc.detail, "code": exc.status_code}),
        status_code=exc.status_code
    )


app.include_router(userMapping, prefix='', tags=['测试：UserMapping'])
app.include_router(loginMapping, prefix='', tags=['用户LoginMapping'])
app.include_router(reviewMapping, prefix='', tags=['点评ReviewMapping'])
app.include_router(groupMapping, prefix='', tags=['分类GroupMapping'])

app.include_router(backendLoginMapper, prefix='/basic-api', tags=['backendLoginMapper'])
app.include_router(reviewsManageMapper, prefix='/basic-api', tags=['reviewsManageMapper'])

if __name__ == '__main__':
    server.run()
